package com.xl.utils.proxystudy.dynamic;

import com.xl.utils.proxystudy.annotation.SysLog;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @Author xionglin
 * @Classname ProxyBean
 * @Description java代理Bean类
 * JDK中动态代理只能代理实现了接口的类
 * @Date 2019/7/1 14:01
 */
public class ProxyBean {

    /**
     * 提供代理的目标对象
     */
    private Object target;


    /**
     * 定义目标对象同一个接口的实现类
     * @param target  传入代理的目标对象
     * @return
     */
    public Object createProxy(final Object target){
        Object obj;
        this.target = target;
        /**
         * 使用jdk中提供的Proxy中的方法实现
         * loader: 目标对象的类加载器
         * interfaces: 目标类实现接口
         * h:回调类必须实现InvocationHandler接口
         */
        obj = Proxy.newProxyInstance(this.target.getClass().getClassLoader(),this.target.getClass().getInterfaces() , new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println(target);
                        System.out.println(proxy.getClass());
                        System.out.println(method.getName());
                        //日志代理，权限代理，访问代理，异常代理
                        //日志处理
                        Method declaredMethod = target.getClass().getDeclaredMethod(method.getName(),method.getParameterTypes());
                        //获取目标对象方法的SysLog注解配置
                        SysLog sysLog = declaredMethod.getAnnotation(SysLog.class);
                        if(sysLog != null){
                            //获取日志中的模块信息
                            String moudle = sysLog.moudle();
                            //获取调用的方法
                            String methodInfo = sysLog.method();
                            System.out.println("我调用了"+moudle+"模块中的"+methodInfo+"方法");
                        }
                        //使用反射调用目标对象的方法
                        Object invoke = method.invoke(target, args);
                        return invoke;
                    }
        });
        return obj;
    }


}
